﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PGMHelper;
using PGMHelper.ProgressForm;

namespace CouplingBeamProject
{
    class MultiStruct
    {
        /// <summary>
        /// 结构列表
        /// </summary>
        private List<MultiStrcutBasic> basicList { set; get; }

        /// <summary>
        /// 楼层数
        /// </summary>
        private int StoreyNumber { set; get; }

        /// <summary>
        /// 层高
        /// </summary>
        private double StoreyHeight { set; get; }

        /// <summary>
        /// 生成文件
        /// </summary>
        public void ToFile()
        {
            //初始化
            var data = new GridViewDatas(string.Format("层数{0}_层高{1}_等效梁放大系数", this.StoreyNumber, this.StoreyHeight));
            //添加数据
            Action<string, int> addColumn = (propertyName, demical) =>
            {
                var valueList = this.basicList.GetPropertyList(propertyName).ConvertAll(d => Convert.ToDouble(d));
                data.Add(new GridViewColumn(valueList, demical, propertyName));
            };
            addColumn("BeamSpan", 0);
            addColumn("BeamHeight", 0);
            addColumn("StoreyHeight", 0);
            addColumn("LeftWallWidth", 0);
            addColumn("RightWallWidth", 0);
            addColumn("StoreyNumber", 0);
            addColumn("EquilibrumBeamFactor", 5);
            //生成文件
            data.ToFile(true, "csv");
        }

        /// <summary>
        /// 生成顶点位移文件
        /// </summary>
        public void ToDispFile()
        {
            //初始化
            var data = new GridViewDatas(string.Format("层数{0}_层高{1}_顶点位移", this.StoreyNumber, this.StoreyHeight));
            //添加数据
            Action<string, int> addColumn = (propertyName, demical) =>
            {
                var valueList = this.basicList.GetPropertyList(propertyName).ConvertAll(d => Convert.ToDouble(d));
                data.Add(new GridViewColumn(valueList, demical, propertyName));
            };
            addColumn("BeamSpan", 0);
            addColumn("BeamHeight", 0);
            addColumn("StoreyHeight", 0);
            addColumn("LeftWallWidth", 0);
            addColumn("RightWallWidth", 0);
            addColumn("StoreyNumber", 0);
            addColumn("CSWWIDisp", 5);
            addColumn("CSWDisp", 5);
            //生成文件
            data.ToFile(true, "csv");
        }

        /// <summary>
        /// 计算等效梁高
        /// </summary>
        public bool Calculate()
        {
            return Process.Run(this.Calculate, ProgressType.Simple, string.Format("层数{0}_层高{1}:等效梁放大系数", this.StoreyNumber, this.StoreyHeight));
        }

        /// <summary>
        /// 计算顶点位移
        /// </summary>
        /// <returns></returns>
        public bool CalculateDisp()
        {
            return Process.Run(this.CalculateDisp, ProgressType.Simple, string.Format("层数{0}_层高{1}:顶点位移", this.StoreyNumber, this.StoreyHeight));
        }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <returns></returns>
        //public bool MultiCalculate()
        //{
        //    var strList = this.basicList.GetPropertyList("BeamSpan").ConvertAll(d => d.ToString());
        //    return MultiProcess.Run(this.MultiCalculate, strList, 3);
        //}

        ///// <summary>
        ///// 多线程
        ///// </summary>
        ///// <param name="obj"></param>
        //private void MultiCalculate(object obj)
        //{
        //    //获得进度
        //    var multiProcess = (SubMultiProcess)obj;
        //    //求等效梁高
        //    this.basicList[multiProcess.Index].SetEquilibrum();
        //    //设定进度条
        //    multiProcess.SetTaskDetail(multiProcess.Index, "求解完成");
        //    multiProcess.SetTaskProgress(multiProcess.Index, 100);
        //    multiProcess.SetTaskSubProgress(multiProcess.Index, 100);
        //    multiProcess.CloseForm(true);
        //}

        /// <summary>
        /// 计算等效梁尺寸放大系数
        /// </summary>
        /// <param name="obj"></param>
        private void Calculate(object obj)
        {
            var process = (Process)obj;
            //设定最大进度
            process.SetMainProcessBoundary(this.basicList.Count);
            //遍历
            this.basicList.ForEach(basic =>
            {
                basic.SetEquilibrum();
                process.AddMainProcess(1);
            });
            process.CloseFrom(true);
        }

        /// <summary>
        /// 计算位移
        /// </summary>
        /// <param name="obj"></param>
        private void CalculateDisp(object obj)
        {
            var process = (Process)obj;
            //设定最大进度
            process.SetMainProcessBoundary(this.basicList.Count);
            //遍历
            this.basicList.ForEach(basic =>
            {
                basic.SetDisp();
                process.AddMainProcess(1);
            });
            process.CloseFrom(true);
        }


        /// <summary>
        /// 实例化
        /// </summary>
        public MultiStruct()
        {
            this.basicList = new List<MultiStrcutBasic>();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public MultiStruct(double BeamSpanMin, double BeamSpanMax, double BeamSpanDelta, double BeamHeightMin, double BeamHeightMax, double BeamHeightDelta, 
            double StoreyHeightMin, double StoreyHeightMax, double StoreyHeightDelta, double LeftWallWidthMin, double LeftWallWidthMax, double LeftWallWidthDelta,
            double WallRatioMin, double WallRatioMax, double WallRatioDelta, int storeynum)
            : this()
        {
            this.StoreyNumber = storeynum;
            for (var beamspan = BeamSpanMin; beamspan <= BeamSpanMax; beamspan += BeamSpanDelta)
            {
                for (var beamheight = BeamHeightMin; beamheight <= BeamHeightMax; beamheight += BeamHeightDelta)
                {
                    for (var storeyheight = StoreyHeightMin; storeyheight <= StoreyHeightMax; storeyheight += StoreyHeightDelta)
                    {
                        for (var leftwallwidth = LeftWallWidthMin; leftwallwidth <= LeftWallWidthMax; leftwallwidth += LeftWallWidthDelta)
                        {
                            for (var wallratio = WallRatioMin; wallratio <= WallRatioMax; wallratio+= WallRatioDelta)
                            {
                                this.basicList.Add(new MultiStrcutBasic(beamspan, beamheight, storeyheight, leftwallwidth, leftwallwidth* wallratio, this.StoreyNumber));
                            }
                        }
                    }
                }                
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public MultiStruct(double BeamSpanMin, double BeamSpanMax, double BeamSpanDelta, double BeamHeightMin, double BeamHeightMax, double BeamHeightDelta,
           double LeftWallWidthMin, double LeftWallWidthMax, double LeftWallWidthDelta,
            double WallRatioMin, double WallRatioMax, double WallRatioDelta, double storeyHeight, int storeynum)
            : this()
        {
            this.StoreyNumber = storeynum;
            this.StoreyHeight = storeyHeight;
            for (var beamspan = BeamSpanMin; beamspan <= BeamSpanMax; beamspan += BeamSpanDelta)
            {
                for (var beamheight = BeamHeightMin; beamheight <= BeamHeightMax; beamheight += BeamHeightDelta)
                {
                    for (var leftwallwidth = LeftWallWidthMin; leftwallwidth <= LeftWallWidthMax; leftwallwidth += LeftWallWidthDelta)
                    {
                        for (var wallratio = WallRatioMin; wallratio <= WallRatioMax; wallratio += WallRatioDelta)
                        {
                            this.basicList.Add(new MultiStrcutBasic(beamspan, beamheight, this.StoreyHeight, leftwallwidth, leftwallwidth * wallratio, this.StoreyNumber));
                        }
                    }
                }
            }
        }
    }

    /// <summary>
    /// 结构基本信息
    /// </summary>
    class MultiStrcutBasic
    {
        /// <summary>
        /// 梁跨度
        /// </summary>
        public double BeamSpan { set; get; }

        /// <summary>
        /// 梁高
        /// </summary>
        public double BeamHeight { set; get; }

        /// <summary>
        /// 层高
        /// </summary>
        public double StoreyHeight { set; get; }

        /// <summary>
        /// 左墙宽
        /// </summary>
        public double LeftWallWidth { set; get; }

        /// <summary>
        /// 右墙宽
        /// </summary>
        public double RightWallWidth { set; get; }

        /// <summary>
        /// 楼层数
        /// </summary>
        public int StoreyNumber { set; get; }

        /// <summary>
        /// 等效梁放大系数
        /// </summary>
        public double EquilibrumBeamFactor { set; get; }

        /// <summary>
        /// 带拉缝模型顶点位移
        /// </summary>
        public double CSWWIDisp { set; get; }

        /// <summary>
        /// 联肢剪力墙模型顶点位移
        /// </summary>
        public double CSWDisp { set; get; }

        ///// <summary>
        ///// 弹模系数
        ///// </summary>
        //public double EModifiedFactor { set; get; }

        /// <summary>
        /// 计算等效参数
        /// </summary>
        public void SetEquilibrum()
        {
            //初始化
            var structure = new Structure();
            //添加楼层
            for (int i = 0; i < this.StoreyNumber; i++)
            {
                structure.AddStoreyInfo(this.LeftWallWidth, this.BeamSpan, this.RightWallWidth, this.BeamHeight,
                this.StoreyHeight, 30, 30, 20);
            }
            //求等效梁放大系数
            this.EquilibrumBeamFactor = structure.GetEquivalResult();
        }

        /// <summary>
        /// 计算带拉缝模型的顶点位移
        /// </summary>
        public void SetDisp()
        {
            //初始化
            var structure = new Structure();
            var structure1 = new Structure();
            //添加楼层
            for (int i = 0; i < this.StoreyNumber; i++)
            {
                structure.AddStoreyInfo(this.LeftWallWidth, this.BeamSpan, this.RightWallWidth, this.BeamHeight,
                this.StoreyHeight, 30, 30, 20);
                structure1.AddStoreyInfo(this.LeftWallWidth, this.BeamSpan, this.RightWallWidth, this.BeamHeight,
                this.StoreyHeight);
            }
            //求位移
            this.CSWWIDisp = structure.GetMaxResponse(1);
            this.CSWDisp = structure1.GetMaxResponse(1);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public MultiStrcutBasic(double span, double beamHeight, double storeyHeight, double leftWallWidth, double rightWallWidth, int storeyNumber)
        {
            this.BeamSpan = span;
            this.BeamHeight = beamHeight;
            this.StoreyHeight = storeyHeight;
            this.LeftWallWidth = leftWallWidth;
            this.RightWallWidth = rightWallWidth;
            this.StoreyNumber = storeyNumber;
            //this.SetEquilibrum();
        }


    }
}
